/*
 * FilePath     : \src\utils\dayjs.ts
 * Author       : SJZ
 * Date         : 2025-03-12 19:28
 * LastEditors  : SJZ
 * LastEditTime : 2025-03-12 20:04
 * Description  : dayjs二次封装
 * CodeIterationRecord: 
 */

import { showMessage } from "./message";
import dayjs, { Dayjs } from "dayjs";
import minMax from "dayjs/plugin/minMax";
import isBetween from "dayjs/plugin/isBetween";
import { CompareResultType } from "./enum";
dayjs.extend(minMax);
dayjs.extend(isBetween);
/**
 * @description: 自定义日期时间比较
 * @return
 */
const compareDates = (date1: string, date2: string, formatter?: DateTimeFormatType | string): CompareResultType => {
  formatter ??= DateTimeFormatType.DATETIME;
  if (!dayjs(date1).isValid() || !dayjs(date2).isValid()) {
    showMessage("error", "入参有误！");
    return CompareResultType.ERROR;
  }
  const formatDate1 = dayjs(date1).format(formatter);
  const formatDate2 = dayjs(date2).format(formatter);
  if (dayjs(formatDate1).isBefore(formatDate2)) {
    return CompareResultType.BEFORE;
  }
  if (dayjs(formatDate1).isSame(formatDate2)) {
    return CompareResultType.SAME;
  }
  return CompareResultType.AFTER;
};
/**
 * @description: 参数规范处理，缩小比较范围
 * @param type
 * @param date
 * @param formatter
 * @return
 */
const convertDateToDateArr = (type: "min" | "max", date?: string | string[], formatter?: DateTimeFormatType) => {
  if (!date) {
    return undefined;
  }
  if (typeof date === "string") {
    return dayjs(date)?.format(formatter);
  }
  const newDateArr = date.filter((date) => date).map((date) => dayjs(date));
  if (newDateArr.length == 0) {
    return "Invalid Date";
  }
  //数组的话返回最大或者最小时间，缩小对比时间范围
  return dayjs[type](newDateArr)?.format(formatter);
};
/**
 * @description: 获取el-date-picker禁用日期
 * @param date
 * @param startDate
 * @param endDate
 * @return
 */
const getDisabledDate = (date: string, startDate?: string | string[], endDate?: string | string[]): boolean => {
  const newDate = dayjs(date).format(DateTimeFormatType.DATE);
  const newStartDate = convertDateToDateArr("max", startDate, DateTimeFormatType.DATE);
  const newEndDate = convertDateToDateArr("min", endDate, DateTimeFormatType.DATE);
  const notDateIndex = [newDate, newStartDate, newEndDate].findLastIndex(
    (dateItem: string | undefined) => !dateItem || dateItem == "Invalid Date"
  );
  switch (notDateIndex) {
    case 0:
      showMessage("error", "入参类型有误！");
      return false;
    case 1:
      return dayjs(newDate).isAfter(newEndDate);
    case 2:
      return dayjs(newDate).isBefore(newStartDate);
    case -1:
      return !dayjs(newDate).isBetween(newStartDate, newEndDate, "D", "[]");
    default:
      return false;
  }
};
/**
 * @description: 获取el-date-picker禁用小时
 * @param date
 * @param startDate
 * @param endDate
 * @return
 */
const getDisabledHour = (date: string, startDate?: string | string[], endDate?: string | string[]): number[] => {
  if (!date) {
    return [];
  }
  const newDate = dayjs(date).format(DateTimeFormatType.DATETIME);
  const newStartDate = convertDateToDateArr("max", startDate, DateTimeFormatType.DATETIME);
  const newEndDate = convertDateToDateArr("min", endDate, DateTimeFormatType.DATETIME);
  const notDateIndex = [newDate, newStartDate, newEndDate].findLastIndex(
    (dateItem: string | undefined) => !dateItem || dateItem == "Invalid Date"
  );
  const dateCheckResult = getDisabledDate(date, startDate, endDate);

  const hourArr = [...Array(24).keys()];
  //日期禁用掉 小时也全部禁用掉
  if (dateCheckResult) {
    return hourArr;
  }
  switch (notDateIndex) {
    case 0:
      showMessage("error", "入参类型有误！");
      return [];
    case 1:
      if (compareDates(newDate, newEndDate!, DateTimeFormatType.DATE) != CompareResultType.SAME) {
        return [];
      }
      return hourArr.filter((hour) => hour > dayjs(newEndDate).hour());
    case 2:
      if (compareDates(newDate, newStartDate!, DateTimeFormatType.DATE) != CompareResultType.SAME) {
        return [];
      }
      return hourArr.filter((hour) => hour < dayjs(newStartDate).hour());
    case -1:
      if (compareDates(newDate, newEndDate!, DateTimeFormatType.DATE) == CompareResultType.SAME) {
        return hourArr.filter((hour) => hour > dayjs(newEndDate).hour());
      }
      if (compareDates(newDate, newStartDate!, DateTimeFormatType.DATE) == CompareResultType.SAME) {
        return hourArr.filter((hour) => hour > dayjs(newEndDate).hour());
      }
    default:
      return [];
  }
};
/**
 * @description: 获取el-date-picker禁用分钟
 * @param date
 * @param startDate
 * @param endDate
 * @return
 */
const getDisabledMinute = (date: string, startDate?: string | string[], endDate?: string | string[]): number[] => {
  if (!date) {
    return [];
  }
  const newDate = dayjs(date).format(DateTimeFormatType.DATETIME);
  const newStartDate = convertDateToDateArr("max", startDate, DateTimeFormatType.DATETIME);
  const newEndDate = convertDateToDateArr("min", endDate, DateTimeFormatType.DATETIME);
  const notDateIndex = [newDate, newStartDate, newEndDate].findLastIndex(
    (dateItem: string | undefined) => !dateItem || dateItem == "Invalid Date"
  );
  const dateHourResult = getDisabledHour(date, startDate, endDate);
  const minuteArr = [...Array(60).keys()];

  //日期禁用掉 小时也全部禁用掉
  if (dateHourResult.length == 0) {
    return minuteArr;
  }
  switch (notDateIndex) {
    case 0:
      showMessage("error", "入参类型有误！");
      return [];
    case 1:
      if (compareDates(newDate, newEndDate!, "YYYY-MM-DD HH") != CompareResultType.SAME) {
        return [];
      }
      return minuteArr.filter((minute) => minute > dayjs(newEndDate).minute());
    case 2:
      if (compareDates(newDate, newStartDate!, "YYYY-MM-DD HH") != CompareResultType.SAME) {
        return [];
      }
      return minuteArr.filter((minute) => minute < dayjs(newStartDate).minute());
    case -1:
      if (compareDates(newDate, newEndDate!, "YYYY-MM-DD HH") == CompareResultType.SAME) {
        return minuteArr.filter((minute) => minute > dayjs(newEndDate).minute());
      }
      if (compareDates(newDate, newStartDate!, "YYYY-MM-DD HH") == CompareResultType.SAME) {
        return minuteArr.filter((minute) => minute > dayjs(newEndDate).minute());
      }
    default:
      return [];
  }
};
/**
 * @description: 自定义插件
 * @param option
 * @param dayjsClass
 * @param dayjsFactory
 * @return
 */
const userPlugin = (option: any, dayjsClass: { prototype: any }, dayjsFactory: any): void => {
  dayjsClass.prototype.now = function (formatter?: string): Dayjs {
    formatter ??= "YYYY-MM-DD HH:mm";
    const timeDiff = Number(sessionStorage.getItem("timeDiff")) || 0;
    return this?.add(timeDiff, "millisecond").format(formatter);
  };
  dayjsClass.prototype.compareDates = compareDates;
  dayjsClass.prototype.getDisabledDate = getDisabledDate;
  dayjsClass.prototype.getDisabledHour = getDisabledHour;
  dayjsClass.prototype.getDisabledMinute = getDisabledMinute;
};
dayjs.extend(userPlugin);

// 导出扩展后的 dayjs
export default dayjs as any;
